//表单验证器
interface FData { //interface可以循环引用自身
    [k: string]: string | number | null | undefined | FData
    // key      : value                              FDAta可能是对象，引用自己
}
type Rule<T> = {//Rule接受t放在key上
    key: keyof T,
    message: string,// 上面是共同的
} & (
        { type: 'required' } |
        { type: "pattern", regex: RegExp }) //不同的
type Rules<T> = Rule<T>[]//接受T
// 所有范型的意思是  如果用T表示 FData的类型 那么 Rule的K必需是T的Key
export type { Rules, Rule, FData }
export const validate = <T extends FData>(FormData: T, rules: Rules<T>) => {
    //加范型 <T> ,T属于FData 把T传给Rules
    type Errors = {
        [k in keyof T]?: string[]
        //Errors的K在 T的key 里面
    }
    const errors: Errors = {} //声明erros是个空对象
    rules.map(rule => {
        const { key, type, message } = rule

        const value = FormData[key]
        switch (type) {
            case 'required':
                if (value === null || value === undefined || value === '') {
                    errors[key] = errors[key] ?? []
                    errors[key]?.push(message)
                }
                break;
            case 'pattern':
                if (value && !rule.regex.test(value.toString())) {
                    errors[key] = errors[key] ?? []
                    errors[key]?.push(message)
                }
                break;
            default:
                return

        }
    })
    return errors
}


